﻿using System.Collections.Generic;
using UnityEngine;

namespace Tools.Log
{
    // 依赖DebugWrapper类，也在库里，记得一起导入
    // 把该脚本直接挂在任何物体上即可

    /// <summary>
    /// 日志的保存
    /// 包括保存所有日志还是日志标签的日志
    /// 保存地址，可以默认保存地址，也可以指定保存的地址（电脑上是默认）
    /// 若果不需要显示 OnGUI（）可以注释掉哈
    /// </summary>
    public class LogManager : MonoBehaviour
    {

        [Tooltip(" TAG 为空记录所有日志，TAG 不为空，只记录 TAG 的日志")]
        [Header("记录日志标签")]
        public string TAG = string.Empty;

        [Tooltip(" saveLogPath 为空日志保存地址为Application.persistentDataPath + ‘/ PlusLogs / ’ + System.DateTime.Now.TimeDay() + ‘_Log.txt’，saveLogPath 不为空，日志保存路径为指定路径")]
        [Header("日志保存地址")]
        public string saveLogPath;

        private System.IO.FileInfo fileLogPath;
        private bool isDebug = true;
        private Queue<string> queueLogs;
        private int maxCount = 1;
        private bool isShowDetail = false;

        void Awake()
        {

            Init();
        }

        /// <summary>
        /// 初始化
        /// </summary>
        void Init()
        {

            // 是否指定日志保存的位置，没有即默认一个位置
            if (string.IsNullOrEmpty(saveLogPath) || Application.platform == RuntimePlatform.WindowsEditor)
            {
                fileLogPath = new System.IO.FileInfo(Application.persistentDataPath + "/LogSaveFiles/" + Application.identifier +
                                                     "-" + Application.productName + "-" + Application.version + "-" + System.DateTime.Now.TimeDay() + "_Log.txt");
            }
            else
            {
                fileLogPath = new System.IO.FileInfo(saveLogPath);
            }

            //  日志队列初始化
            queueLogs = new Queue<string>();

            // 查看是否有指定的路径日志文件
            if (!fileLogPath.Exists)
            {

                if (!System.IO.Directory.Exists(fileLogPath.DirectoryName))
                {
                    System.IO.Directory.CreateDirectory(fileLogPath.DirectoryName);
                }
                fileLogPath.Create();
            }

            //Application.RegisterLogCallback(HandleLog);老版本这么写的
            Application.logMessageReceived += HandleLog;

            if (isDebug)
            {
                DebugWrapper.Log("初始化日志文件成功，日志保存路径为 : " + fileLogPath.FullName);
            }

        }


        /// <summary>
        /// 系统处理日志的事件函数
        /// </summary>
        /// <param name="logString"></param>
        /// <param name="stackTrace"></param>
        /// <param name="type"></param>
        void HandleLog(string logString, string stackTrace, LogType type)
        {
            // 是否过滤只保存需要的日志（TAG 为要保存的日志标签）
            if (string.IsNullOrEmpty(TAG) == false)
            {
                if (logString.Contains(TAG) == false)
                {
                    return;
                }
            }

            // 处理日志字符串
            string[] s = stackTrace.Split('\n');
            stackTrace = string.Empty;
            foreach (string line in s)
            {
                stackTrace += "      " + line + '\n';
            }

            // 把日志添加到队列中
            lock (queueLogs)
            {
                queueLogs.Enqueue(string.Format("{0} : {1}\r\n{2}  {3}", type, logString, stackTrace, "\n"));

                // 日志队列满足数量，及保存日志
                if (queueLogs.Count >= maxCount)
                {
                    WriteLocal();
                }
            }
        }

        /// <summary>
        /// 写入日志文件
        /// </summary>
        void WriteLocal()
        {
            try
            {
                using (System.IO.StreamWriter file = new System.IO.StreamWriter(fileLogPath.FullName, true))
                {
                    while (queueLogs.Count > 0)
                    {
                        file.Write(queueLogs.Dequeue());//直接追加文件末尾  
                    }
                }
            }
            catch (System.Exception e)
            {
                throw (e);
            }
        }

        /// <summary>
        /// 读取日志文件
        /// </summary>
        /// <returns></returns>
        public string ReadLogFile()
        {
            try
            {
                return System.IO.File.ReadAllText(fileLogPath.FullName);
            }
            catch (System.Exception e)
            {
                return "日志文件读取错误:" + e.Message;
            }

        }


        private Vector2 scrollViewVector = Vector2.zero;
        /// <summary>
        /// 绘制在界面上查看日志信息
        /// </summary>
        void OnGUI()
        {
            // 调试的时候显示窗口
            if (isDebug)
            {
                // 显示或关闭日志显示
                if (isShowDetail)
                {

                    GUI.TextArea(new Rect(0, 100, Screen.width, Screen.height - 100), ReadLogFile());


                }
            }
        }

        public void ShowDetail()
        {
            isShowDetail = true;
        }
        public void CloseDetail()
        {
            isShowDetail = false;
        }

        /// <summary>
        /// 在销毁的时候，把未保存的保存下（任选一个）
        /// </summary>
        void OnDestroy()
        {
            //Debug.Log("XAB OnDestroy  WriteLocal()");
            //WriteLocal();
        }

        /// <summary>
        /// 在退出应用的时候，把未保存的保存下（任选一个）
        /// </summary>
        void OnApplicationQuit()
        {
            //Debug.Log("XAB OnApplicationQuit  WriteLocal()");
            WriteLocal();
        }
    }
}
// 把该脚本直接挂在任何物体上即可